package com.douqu.game.activity.web.controller;

import com.bean.core.util.MD5Utils;
import com.bean.core.util.TimeUtils;
import com.douqu.game.activity.GameServer;
import com.douqu.game.activity.entity.MainServerInfo;
import com.douqu.game.activity.entity.camp.CampPlayer;
import com.douqu.game.activity.manager.ActivityCampManager;
import com.douqu.game.activity.manager.LoadManager;
import com.douqu.game.activity.util.CosUtils;
import com.douqu.game.core.e.E_ActivityCampStatus;
import com.douqu.game.core.e.ReturnMessage;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.factory.LoadFactory;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.web.response.BaseResponseDto;
import com.douqu.game.core.web.response.ErrorResponseDto;
import com.douqu.game.core.web.response.SuccessResponseDto;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Time;
import java.util.*;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-04-08 14:57
 */
@RestController
@RequestMapping(value = "/camp")
public class CampController {

    @RequestMapping(value = "/serverStart", produces = "application/json;charset=UTF-8")
    public BaseResponseDto serverStart(Integer id, String host, Integer port, String password)
    {
        if(id <= 0 || port <= 0 || CoreUtils.isNullOrEmpty(host))
        {
            LogUtils.error("参数错误!");
            return new BaseResponseDto(ReturnMessage.PARAM_ERROR);
        }

        String checkString = id + "" + TimeUtils.getCurrentTime(TimeUtils.YYYYMMDD);
        LogUtils.debug("checkString -> " + checkString);
        String md5Code = MD5Utils.encodeUppercase(checkString);
        if(!md5Code.equals(password))
        {
            LogUtils.error("changeStatus 密码错误, 正确密码：" + md5Code + ",传递的密码 -> " + password);
            return new ErrorResponseDto(ReturnMessage.PASSWORD_ERROR);
        }

        if(GameServer.getInstance().getMainServerInfo(host, port) == null)
        {
            LogUtils.warn("HTTP收到通知，服务器开启 -> id:" + id + ",host:" + host + ",port:" + port);
            new MainServerInfo(id, host, port).startTCP();

            return new BaseResponseDto(ReturnMessage.SUCCESS);
        }
        else
        {
            return new BaseResponseDto(ReturnMessage.SERVER_IS_STARTED);
        }
    }



    @RequestMapping(value = "/checkApply", produces = "application/json;charset=UTF-8")
    public BaseResponseDto checkApply()
    {
        int maxPerson = GameServer.getInstance().getActivityCampManager().getActivityCampModel().getMaxPersonCount();
        int curPerson = GameServer.getInstance().getActivityCampManager().getPlayerList().size();

        ReturnMessage result = ReturnMessage.SUCCESS;
        if(curPerson >= maxPerson)
            result = ReturnMessage.APPLY_COUNT_MAX;

        return new BaseResponseDto(result);
    }

    @RequestMapping(value = "/playerList", produces = "application/json;charset=UTF-8")
    public BaseResponseDto playerList(Integer page, Integer count, String keyword)
    {
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> data = null;
        CampPlayer campPlayer = null;
        List<CampPlayer> playerList = GameServer.getInstance().getActivityCampManager().getPlayerList();

        int totalCount = 0;
        if(CoreUtils.isNullOrEmpty(keyword))
        {
            page = page == null ? 1 : page.intValue();
            count = count == null ? 20 : count.intValue();

            int size = playerList.size();
            int totalPage = (size%count==0)?(size/count):(size/count+1);
            page = page > totalPage ? totalPage : page;
            int start = (page - 1) * count;
            start = start < 0 ? 0 : start;
            start = start > size ? size : start;
            int end = start + count;
            end = end > size ? size : end;

            for(int i = start; i < end; i++)
            {
                campPlayer = playerList.get(i);
                data = new HashMap<>();
                data.put("name", campPlayer.getPlayerBase().getName());
                data.put("serverName", GameServer.getInstance().getServerNameRemark(campPlayer.getPlayerBase().getServerId()));
                data.put("camp", campPlayer.getPlayerBase().getCamp());
                data.put("lv", campPlayer.getPlayerBase().getLv());
                data.put("fc", campPlayer.getPlayerBase().getFc());
                data.put("winRate", campPlayer.getPlayerBase().getWinRate());
                data.put("createTime", campPlayer.getCreateTime());
                list.add(data);
            }

            totalCount = playerList.size();
        }
        else
        {
            for(CampPlayer player : playerList)
            {
                if(player.getPlayerBase().getName().indexOf(keyword) != -1)
                {
                    data = new HashMap<>();
                    data.put("name", player.getPlayerBase().getName());
                    data.put("serverName", GameServer.getInstance().getServerNameRemark(player.getPlayerBase().getServerId()));
                    data.put("camp", player.getPlayerBase().getCamp());
                    data.put("lv", player.getPlayerBase().getLv());
                    data.put("fc", player.getPlayerBase().getFc());
                    data.put("winRate", player.getPlayerBase().getWinRate());
                    data.put("createTime", player.getCreateTime());
                    list.add(data);

                    totalCount++;
                }
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("page", page);
        result.put("count", count);
        result.put("totalCount", totalCount);
        result.put("list", list);

        return new SuccessResponseDto(result);
    }

    @RequestMapping(value = "/matchPlayerList", produces = "application/json;charset=UTF-8")
    public BaseResponseDto matchPlayerList(Integer camp, String keyword)
    {
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> data = null;
        for(CampPlayer player : GameServer.getInstance().getActivityCampManager().getMatchPlayerList(camp==null?0:camp.intValue()))
        {
            if(!CoreUtils.isNullOrEmpty(keyword) && player.getPlayerBase().getName().indexOf(keyword) == -1)
                continue;

            data = new HashMap<>();
            data.put("name", player.getPlayerBase().getName());
            data.put("serverName", GameServer.getInstance().getServerNameRemark(player.getPlayerBase().getServerId()));
            data.put("camp", player.getPlayerBase().getCamp());
            data.put("lv", player.getPlayerBase().getLv());
            data.put("fc", player.getPlayerBase().getFc());
            data.put("winRate", player.getPlayerBase().getWinRate());
            data.put("createTime", player.getCreateTime());
            list.add(data);
        }
        return new SuccessResponseDto(list);
    }

    @RequestMapping(value = "/rankPlayerList", produces = "application/json;charset=UTF-8")
    public BaseResponseDto rankPlayerList()
    {
        return new SuccessResponseDto(GameServer.getInstance().getActivityCampManager().getRankPlayerList());
    }

    @RequestMapping(value = "/rankCampList", produces = "application/json;charset=UTF-8")
    public BaseResponseDto rankCampList()
    {
        return new SuccessResponseDto(GameServer.getInstance().getActivityCampManager().getRankCampList());
    }

    @RequestMapping(value = "/maxData", produces = "application/json;charset=UTF-8")
    public BaseResponseDto maxRankData()
    {
        Map<String, Object> data = new HashMap<>();

        ActivityCampManager activityCampManager = GameServer.getInstance().getActivityCampManager();

        data.put("maxContinueWinPlayer", activityCampManager.getMaxContinueWinPlayer());
        data.put("maxExploitPlayer", activityCampManager.getMaxExploitPlayer());
        data.put("maxWinCountPlayer", activityCampManager.getMaxWinCountPlayer());

        return new SuccessResponseDto(data);
    }

    @RequestMapping(value = "/all", produces = "application/json;charset=UTF-8")
    public BaseResponseDto totalRank()
    {
        Map<String, Object> data = new HashMap<>();

        ActivityCampManager activityCampManager = GameServer.getInstance().getActivityCampManager();

        data.put("maxContinueWinPlayer", activityCampManager.getMaxContinueWinPlayer());
        data.put("maxExploitPlayer", activityCampManager.getMaxExploitPlayer());
        data.put("maxWinCountPlayer", activityCampManager.getMaxWinCountPlayer());
        data.put("rankCampList", GameServer.getInstance().getActivityCampManager().getRankCampList());
        data.put("rankPlayerList", GameServer.getInstance().getActivityCampManager().getRankPlayerList());

        return new SuccessResponseDto(data);
    }


    @RequestMapping(value = "/clearRank", produces = "application/json;charset=UTF-8")
    public BaseResponseDto clearRank()
    {
        GameServer.getInstance().getActivityCampManager().clearRank();
        return new SuccessResponseDto();
    }


    @RequestMapping(value = "/serverList", produces = "application/json;charset=UTF-8")
    public BaseResponseDto serverList()
    {

        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> data = null;
        List<MainServerInfo> serverInfoList = GameServer.getInstance().getMainServerList();
        for(MainServerInfo mainServerInfo : serverInfoList)
        {
            data = new HashMap<>();
            data.put("id", mainServerInfo.getId());
            data.put("host", mainServerInfo.getHost());
            data.put("port", mainServerInfo.getPort());
            list.add(data);
        }
        return new SuccessResponseDto(list);
    }



    @RequestMapping(value = "/updateConfig", produces = "application/json;charset=UTF-8")
    public BaseResponseDto updateConfig(int id, String version, String password)
    {
        if(id <= 0)
        {
            LogUtils.error("参数错误!");
            return new BaseResponseDto(ReturnMessage.PARAM_ERROR);
        }

        String checkString = id + "" + TimeUtils.getCurrentTime(TimeUtils.YYYYMMDD);
        LogUtils.debug("checkString -> " + checkString);
        String md5Code = MD5Utils.encodeUppercase(checkString);
        if(!md5Code.equals(password))
        {
            LogUtils.error("changeStatus 密码错误, 正确密码：" + md5Code + ",传递的密码 -> " + password);
            return new ErrorResponseDto(ReturnMessage.PASSWORD_ERROR);
        }

        return null;
    }

    /**
     * 在slgmanager上修改了阵营战配置，调用这个接口通知
     * @param id
     * @param password
     * @return
     */
    @RequestMapping(value = "/updateActivityConfig", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
    public BaseResponseDto updateActivityConfig(Integer id, String password)
    {
        if(GameServer.getInstance().getActivityCampManager().getStatus() != E_ActivityCampStatus.FREE)
        {
            LogUtils.error("活动正在进行中，不允许更新");
            return new ErrorResponseDto(ReturnMessage.ILLEGAL);
        }

        if(id == null || id <= 0 || id != GameServer.getInstance().getActivityCampManager().getId())
        {
            LogUtils.error("参数错误 -> id:" + id + "  password:" + password);
            return new BaseResponseDto(ReturnMessage.PARAM_ERROR);
        }

        String checkString = id + "" + TimeUtils.getCurrentTime(TimeUtils.YYYYMMDD);
        LogUtils.debug("updateActivityConfig checkString -> " + checkString);
        String md5Code = MD5Utils.encodeUppercase(checkString);
        if(!md5Code.equals(password))
        {
            LogUtils.error("changeStatus 密码错误, 正确密码：" + md5Code + ",传递的密码 -> " + password);
            return new ErrorResponseDto(ReturnMessage.PASSWORD_ERROR);
        }

        //TODO 当天活动开始后不允许再修改配置
        Time startTime = GameServer.getInstance().getActivityCampManager().getActivityCampModel().getStartTime();
        Date currentTime = TimeUtils.getCurrentDate();
        if((currentTime.getHours() == startTime.getHours() && currentTime.getMinutes() + 5 >= startTime.getMinutes()) || currentTime.getHours() > startTime.getHours())
        {
            //开始活动前5分钟不允许再修改
            LogUtils.error("活动开始前5分钟不允许修改");
            return new ErrorResponseDto(ReturnMessage.UPDATE_ACTIVITY_CONFIG_TIME_ERROR);
        }
        LogUtils.info("阵营战斗配置更新，重新载入");
        //通知配置更新了，去数据库重新加载
        GameServer.getInstance().getActivityCampManager().reloadModelConfig();

        return new BaseResponseDto(ReturnMessage.SUCCESS);
    }


    @RequestMapping(value = "/updateObjectConfig", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
    public BaseResponseDto updateObjectConfig(String path, String version, String password)
    {
        //验证密码
        String md5Code = CoreUtils.MD5Encode(GameServer.getInstance().getActivityCampManager().getId() + "" + version + "" + TimeUtils.getCurrentTime(TimeUtils.YYYYMMDD));//固定密码
        if(!md5Code.equals(password))
        {
            LogUtils.error("changeStatus 密码错误, 正确密码：" + md5Code);
            LogUtils.debug("update version fail ......... version : " + version );
            return new ErrorResponseDto(ReturnMessage.PASSWORD_ERROR);
        }

        boolean result = CosUtils.downloadFile(path);
        if (result)
        {
            LoadFactory.setTestLoad(true);

            LoadManager.testLoad();

            List<String> errorList = DataFactory.getInstance(true).getErrorList();

            LoadFactory.setTestLoad(false);

            if (errorList.size() == 0)
            {
                LogUtils.info("GM开始更新配置文件,服务器暂停使用=========================================");

                LoadManager.load();

                //通知战斗服务器更新配置
                GameServer.getInstance().sendToBattleServerUpdateConfig();

                GameServer.getInstance().getActivityCampManager().getActivityCampModel().setVersion(version);
            }

            LogUtils.info("更新配置文件结果 -> " + errorList);

            return new ErrorResponseDto(errorList);
        } else {
            return new ErrorResponseDto(ReturnMessage.UPDATE_ACTIVITY_CONFIG_NET_ERROR);
        }
    }


}
